package com.example.controller;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.dto.AuthorDTO;
import com.example.dto.BookDTO;
import com.example.entities.Author;
import com.example.entities.Book;
import com.example.repository.AuthorRepository;
import com.mongodb.client.result.UpdateResult;

import dev.morphia.Datastore;
import dev.morphia.UpdateOptions;
import dev.morphia.query.experimental.filters.Filters;
import dev.morphia.query.experimental.updates.UpdateOperators;

@RestController
@RequestMapping("/")
public class TestController {
	
	@Autowired
	AuthorRepository authorRepository;
 
    @Autowired
    Datastore datastore;
 
    @PostMapping("/book/create")
    public String createBook(@RequestBody BookDTO bookDTO) {
        //查询作者
        Author author = datastore.find(Author.class)
                .filter(Filters.eq("name", bookDTO.getAuthorName()))
                .iterator().next();
 
        //简单转换
        Book book = new Book();
        book.setTitle(bookDTO.getTitle());
        book.setTags(Arrays.asList(bookDTO.getTags().split(",").clone()));
        book.setDescription(bookDTO.getDescription());
        //忽略时间
        book.setPublishDate(new Date());
        book.setAuthor(author);
 
        Book result = datastore.save(book);
        if (result != null) {
            return result.getTitle();
        }
        return "failure";
    }
 
    @GetMapping("/book/list")
    public List<BookDTO> getBookList(@RequestParam("authorName") String authorName) {
 
        Author author = datastore.find(Author.class)
                .filter(Filters.eq("name", authorName))
                .iterator().next();
 
        List<BookDTO> books = datastore.find(Book.class)
                .filter(Filters.eq("author", author.getId()))
                .stream().map(m -> new BookDTO(m.getTitle(), String.join(",", m.getTags()), m.getDescription(),
                        m.getAuthor().getName()))
                .collect(Collectors.toList());
 
        return books;
    }
 
    @GetMapping("/book/get")
    public BookDTO getBook(@RequestParam("title") String title) {
        List<BookDTO> books = datastore.find(Book.class)
                .filter(Filters.eq("title", title))
                .stream().map(m -> new BookDTO(m.getTitle(), String.join(",", m.getTags()), m.getDescription(),
                        m.getAuthor().getName()))
                .collect(Collectors.toList());
 
        return books.size() > 0 ? books.get(0) : null;
    }
 
    @PostMapping("/book/tags/add")
    public String addBookTag(@RequestParam("title") String title, @RequestParam List<String> tags) {
        UpdateResult result = datastore.find(Book.class)
                .filter(Filters.eq("title", title))
                .update(UpdateOperators.addToSet("tags", tags))
                .execute();
 
        return result.toString();
    }
 
    @PostMapping("/book/tags/remove")
    public String removeBookTag(@RequestParam("title") String title, @RequestParam List<String> tags) {
        UpdateResult result = datastore.find(Book.class)
                .filter(Filters.eq("title", title))
                .update(UpdateOperators.pullAll("tags", tags))
                .execute(new UpdateOptions().multi(false));
        return result.toString();
    }
 
    @PostMapping("/author/create")
    public String createAuthor(@RequestBody AuthorDTO authorDTO) {
        //简单转换
        Author author = new Author();
        author.setName(authorDTO.getName());
        author.setSex(authorDTO.getSex());
        author.setAge(authorDTO.getAge());
        author.setAddress(authorDTO.getAddress());
        author.setPhone(authorDTO.getPhone());
 
        author = datastore.save(author);
        if (author != null) {
            return author.getName();
        }
        return "failure";
    }
    
    @RequestMapping("/author/create-sim")
    public String createAuthorSim() {
        //简单转换
        Author author = new Author();
        author.setName("sim");
        author.setSex("1");
        author.setAge(18);
        author.setAddress("hello");
        author.setPhone("13590283465");
        author = datastore.save(author);
        if (author != null) {
            return author.getName();
        }
        return "failure";
    }
    
    @RequestMapping("/author/list")
    public List<Author> authorList() {
        //简单转换
    	List<Author> authoris = authorRepository.findAll();
        return authoris;
    }
}